# 数据容器入门
"""
Python中的数据容器: 一种可以存储多个元素的Python数据类型
一种可以容纳多份数据的数据类型，容纳的每一份数据称之为1个元素。每一个元素，可以是任意类型的数据，如字符串、数字、布尔等

数据容器根据特点的不同，如:
    是否支持重复元素
    是否可以修改
    是否有序，等
分为5类，分别是:
    列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)我们将--学习它们
"""



# list(列表)的定义语法
"""
1、列表的定义
基本语法：
# 字面量
[元素1, 元素2, 元素3, 元素4, .....]
# 变量
name = [元素1, 元素2, 元素3, 元素4, .....]
# 定义空列表
name = []
name = list()    # name为变量，而list()是用来创建新的空列表的函数

列表内的每一个数据，称之为元素
    以[]作为标识
    列表内每一个元素之间用，逗号隔开
# 案例1
name_list = ['three', 'two', 'one']
print(name_list)             # 打印['three', 'two', 'one']
print(type(name_list))       # <class 'list'>

注意:列表可以一次存储多个数据，且可以为不同的数据类型，支持嵌套
# 定义一个嵌套列表
name_list = [[1, 2, 3], [4, 5, 6]]
print(name_list)
print(type(name_list))
"""

# 列表的下标索引
"""
下表索引：列表中每一个元素，都有其位置的下表索引。从前往后的方向。从0开始，依次递增
注意：提供下标索引取数据，一定不要超出范围
语法： 列表[索引号]
# 例子 下表索引
name_list = ["TOM", "LILy", "Rose"]
print(name_list[0])   # 结果：TOM
print(name_list[1])   # 结果：LULy
print(name_list[2])   # 结果：Rose

# 列表的下表索引----反向
    也叫反向索引，也就是从后向前，从-1开始依次递减
name_list = ["安东", "菊花", "桃花"]
print(name_list[-1])
print(name_list[-2])
print(name_list[-3])


# 列表嵌套，同样支持下标索引
name_list = [[1, 3, 4], [4, 5, 6]]
print(name_list[1][1])            # 打印5
"""

# 列表的常用操作
"""
列表除了可以:
    定义
    使用下标索引获取值
以外，列表也提供了一系列功能:
    插入元素
    删除元素
    清空列表
    修改元素
    统计元素个数
等等功能，这些功能我们都称之为:列表的方法

回忆:函数是一个封装的代码单元，可以提供特定功能。
在Python中，如果将函数定义为class(类)的成员，那么函数会称之为:方法
函数：
def add(x, y):
    return x+y
方法：
class Student:
    def add(x, y):
    return x+y

方法和函数功能一样，有传入参数，有返回值，只是方法的使用格式不同:
函数的调用：num = add(1, 2)
方法的使用：student = student()
          num = student.add(1, 2)
          
# 列表的查询功能(方法)
查找某元素的下标
    功能:查找指定元素在列表的下标如果找不到，报错ValueError
    语法:列表.jndex(元素)
    index就是列表对象(变量)内置的方法(函数)
# 示例1
my_list = ["andong", "itheima", "python"]
# 查找某元素在列表中的下表索引
index = my_list.index("itheima")
print(f"itheima在列表中的下表索引值是：{index}")     # 打印1

# 列表的修改功能（方法）
修改特定位置(索引)的元素值:
    语法:列表[下标]=值
    可以使用如上语法，直接对指定下标(正向、反向下标均可)的值进行:重新赋值(修改)
# 正向赋值
num_list = [1, 2, 3, 4, 5, 8, [1, 3, 4]]
num_list[2] = 6
num_list[6][1] = 7
print(num_list)
# 反向赋值
num_list = [1, 2, 3, 4, 5, 8, [1, 3, 4]]
num_list[-2] = 6
num_list[-3] = 7
print(num_list)            # 打印[1, 2, 3, 4, 7, 6, [1, 2, 4]]

# 列表中元素的插入
插入元素:
    语法:列表.insert(下标,元素)，在指定的下标位置，插入指定的元素
# 列表的插入
num_list = [1, 2, 3, 4]
num_list.insert(2, 9)
print(num_list)         # 打印[1, 2, 9, 3, 4]

# 列表中元素的追加
语法1追加单个:列表.append(元素)，将指定元素，只能追加到列表的尾部
语法2追加一批:列表.extend(其它数据容器)，将其它数据容器的内容取出，依次追加到列表尾部

# 在列表中追加单个元素
num_list = [1, 2, 3]
num_list.append(4)
print(num_list)           # 打印结果[1, 2, 3, 4]
# 在列表中添加一批元素
num_list = [1, 2, 3]
num_list1 = [4, 5 ,6]
num_list.extend(num_list1)
print(num_list)          # 打印结果[1, 2, 3, 4, 5, 6]

# 删除元素
语法1: del 列表[下标]
语法2:列表.pop(下标)
num_list = [1, 2, 3, 4, 5]
del num_list[4]          # 语法1，使用del指定下标进行删除
ele = num_list.pop(3)          # 语法2 使用pop函数
print(f"通过pop方法生成列表后内容：{num_list}，取出的值为{ele}")      # 通过pop方法删除列表后内容：[1, 2, 3]，取出的值为4

# 删除某元素在列表中的第一个匹配项
   语法:列表.remove(元素)
num_list = [1, 2, 3, 4, 5, 3]
num_list.remove(3)
print(num_list)                 # 打印[1, 2, 4, 5, 3]

# 清空列表内容。   语法:列表.clear()
num_list = [1, 2, 3, 4, 5, 3]
num_list.clear()
print(num_list)    # 打印[]

# 统计某一个元素在列表中的次数
语法：列表.count(元素)
num_list = [1, 2, 3, 4, 5, 3]
num = num_list.count(3)
print(num)               # 打印2

# 统计列表内，有多少元素
    语法:len(列表)
可以得到一个int数字，表示列表内的元素数量
num_list = [1, 2, 3, 4, 5, 3]
num = len(num_list)
print(num)         # 打印6

# 列表的特点
经过上述对列表的学习，可以总结出列表有如下特点:
    可以容纳多个元素(上限为2**63-1、9223372036854775807个)
    可以容纳不同类型的元素(混装)
    数据是有序存储的(有下标序号)
    允许重复数据存在
    可以修改(增加或删除元素等)
    
# 列表练习 定义一个列表
age = [21, 25, 21, 23, 22, 20]
# 追加数字31到尾部
age.append(31)
# 追加新列表[29, 33, 30]到列表尾部
age_a = [29, 33, 30]
age.extend(age_a)
# 取出第一个元素（应是21）
num = age[0]
print(f"应是：{num}")         # 打印21
# 取出最后一个元素，应是30
num_1 = age[-1]
print(f"应是：{num_1}")       # 打印30
# 找出元素31在列表中的下标位置
index = age.index(31)
print(index)          # 打印为6
print(age)     # 打印为[21, 25, 21, 23, 22, 20, 31, 29, 33, 30]
"""

# 列表的遍历
"""
列表的遍历-while循环
既然数据容器可以存储多个元素，那么，就会有需求从容器内依次取出元素进行操作。
将容器内的元素依次取出进行处理的行为，称之为:遍历、迭代。

1.可以通过while循环取出元素
    ---通过列表下标索引的方式取出
    ---定义一个变量表示下标，从0开始  ---循环条件为下标值<列表的元素数量
        index = 0
            while index < len(列表)
            元素=len(index)
            对元素进行处理
            index += 1
# while循环遍历列表
def list_while_func():
    my_list = ["1111", "2222", "3333", "4444"]
    index = 0    # 初始值为0
    while index < len(my_list):     # 使用len()内置函数就可以计算出列表的个数
        count = (my_list[index])
        print(f"列表的元素为：count")

        index += 1         # 将循环变量每一次的都加1
list_while_func()

# 使用for循环对列表进行遍历     ---更适合对列表数据进行遍历
语法:
for 临时变量 in 数据容器:
    对临时变量进行处理
表示，从容器内，依次取出元素并赋值到临时变量上。
在每一次的循环中，我们可以对临时变量(元素)进行处理。
# for循环遍历列表
def list_for_func():
    my_list = [1, 2, 3, 4, 5, 6]
    for i in my_list:
        print(f"列表的元素有{i}")

list_for_func()

while循环和for循环，都是循环语句，但细节不同:
在循环控制上:
    whle循环可以自定循环条件，并自行控制
    for循环不可以自定循环条件，只可以一个个从容器内取出数据
在无限循环上:
    while循环可以通过条件控制做到无限循环
    for循环理论上不可以，因为被遍历的容器容量不是无限的
在使用场景上:
    while循环适用于任何想要循环的场景
    for循环适用于，遍历数据容器的场景或简单的固定次数循环场景
num_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
count = []
count_a = 0
# 通过while循环遍历列表
while count_a < len(num_list):
    app = num_list[count_a]

    if app % 2 == 0:
        count.append(num_list[count_a])
    count_a += 1
print(f"通过while循环，从列表{num_list}取出偶数，组成列表为{count}")
# 通过for循环遍历列表

for x in num_list:
    if x % 2 == 0:
        count.append(x)
print(f"用for循环，遍历列表{num_list},找到偶数并组成的新列表是：{count}")
"""





# 元组的定义和操作
"""
元组同列表一样，都是可以封装多个、不同类型的元素在内。但最大的不同点在于:
元组一旦定义完成，就不可修改

元组定义:定义元组使用小括号，且使用逗号隔开各个数据，数据可以是不同的数据类型。
# 定义字面量
(元素1, 元素2, 元素3, 元素3)
# 定义元组变量
name = (元素1, 元素2, 元素3, 元素3)
# 定义空元组
name = ()
name = tuple()  # 本质上来说，是得到了一个元组类对象
基础定义：
name = (1, 2, 3, 4)
print(name)                   # 打印(1, 2, 3, 4)
print(type(name))             # 打印<class 'tuple'>

# 注意：如果元组内只要一个数据，这个数据后面要添加逗号。
name = (1, )
print(type(name))       # 打印class tuple


# 元组的嵌套
t5 = ((1, 2, 3), (4, 5, 6))


# 通过下标索引取出数据
t5 = ((1, 2, 3), (4, 5, 6))
num = t5[1][2]
print(num)    # 打印6


# 元组的相关操作
index()     查找某个数据，如果数据存在会返回对应的下标，否则报错
count()     统计某个数据在当前元组出现的次数
len(元组)    统计元组内的元素个数
t1 = (1, 2, 2, 2, "hello")
index = t1.index("hello")
name = t1.count(2)
len_a = len(t1)
print(index)           # 打印2
print(name)            # 打印3
print(len_a)           # 打印5


# 元组的遍历：while
index = 0
t1 = (1, 2, 3, 4, 5, 6, 6)

while index < len(t1):
    index_a = t1[index]
    print(index_a)    
    index += 1    # 至关重要

# 元组的遍历：for
t1 = (1, 2, 3, 4, 5, 6, 6)
for x in t1:
    print(x)


# 注意事项
1.元组不能修改，否则会报错
2.可以修改元组内的list内容（修改，增加，删除）
name = (1, 2, [4, 5, 6])
# 修改列表内的1号元素
name[2][1] = 9
print(name)     # 打印(1, 2, [4, 9, 6])

# 元组的特点：
经过上述对元组的学习，可以总结出列表有如下特点:
    可以容纳多个数
    可以容纳不同类型的数据(混装)
    数据是有序存储的[下标索引)
    允许重复数据存在
    不可以修改(增加或删除元素等)
    支持for循环
多数特性和list一致，不同点在于不可修改的特性。


# 练习
data = ("周杰伦", 11, ["football", "music"])
age = data.index(11)   # 查询年龄的下标
name = data[0]   # 查询姓名
delete = data[2].pop(0)   # 删除football
# del data[2][0]            # 删除football
# data[2].remove('football')  删除football
hobby = data[2].append('hobby')   # 追加爱好coding到列表里
print(f"age: {age}, name: {name}, delete: {delete}, hobby： {hobby}")
print(data)
"""






# 字符串的定义和操作
"""
字符串是字符的容器，一个字符串可以存放任意数量的字符。
字符串可以看出字符的容器，支持下标索引特性。
同元组一样，字符串是一个:无法修改的数据容器。如果非要修改，只能得到一个新的字符串。 name[2] = H;会报错
# 下标索引
name = "itheima"
print(name[2])  # 正向取h ，打印h
print(name[-5])  # 反向取h ，打印h

# index方法
name = "itheima and itcast"
value = name.index('and')
print(f"查找and起始下标是{value}")    # 查找and起始下标是8

# replace方法，字符串的替换
语法:字符串.replace(字符串1，字符串2)
功能:将字符串内的全部:字符串1替换为字符串2
注意:不是修改字符串本身，而是得到了一个新字符串哦！会得到一个返回值。

name = "itheima and itcast"
new_name = name.replace("it", "程序")
print(f"将字符串{name}, 进行替换后得到{new_name}")   
# 将字符串itheima and itcast, 进行替换后得到程序heima and 程序cast


# split方式（字符串的分割）
语法：字符串.split(分割符字符串)
功能:按照指定的分隔符字符串，将字符串划分为多个字符串，并存入列表对象中
注意:字符串本身不变，而是得到了一个列表对象
# 使用空格作为分隔符
my_name = "my_utils name is itheima"
my_name_list = my_name.split()
print(my_name_list)
# 使用逗号作为分割符
s = "apple,banana,cherry"
fruits = s.split(',')  # 使用逗号作为分割符
print(fruits)  # 输出：['apple', 'banana', 'cherry']
# 可以指定分割符的最大分割次数
s = "apple,banana,cherry,date"
fruits = s.split(',', 2)    # 最多分2次
print(fruits)   # 打印['apple', 'banana', 'cherry,date']

# strip方法（字符串的规整操作）
字符串的规整操作(去除前后空格以及换行符)
语法:字符串.strip()
# 不传入参数，去除首位空格
name = "  hello python itheima itcast  "
new_name = name.strip()
print(f"字符串{name}进行strip切分后得到：{new_name}")
# 字符串  hello python itheima itcast  进行strip切分后得到：hello python itheima itcast


字符串的规整操作(去除前后指定字符串)
语法:字符串.strip(字符串)
# 注意，传入的是“12”其实就是:”1”和”2”都会移除，是按照单个字符。
name = "12hello python itheima itcast21"
new_name = name.strip("12")
print(f"字符串{name}被.strip(12)后，结果为：{new_name}") 
# 打印字符串12hello python itheima itcast21被.strip(12)后，结果为：hello python itheima itcast

# 统计某个元素在字符串中的出现的次数
name = "hello python itheima itcast"
count = name.count('it')
print(f"字符串{name}中出现{count}次'it'")
# 字符串hello python itheima itcast中出现2次'it'

#统计字符串长度
name = "hello and itcast"
num = len(name)
print(f'字符串{name}的长度是{num}')  # 字符串hello and itcast的长度是16


# 字符串的遍历
my_str = '黑马程序员'
index = 0
# 使用while遍历
while index < len(my_str):
    print(my_str[index])
    index += 1
# 使用for遍历字符串
for x in my_str:
    print(x)
    

# 字符串特点
作为数据容器，字符串有如下特点:
    只可以存储字符串
    长度任意(取决于内存大小)
    支持下标索引
    允许重复字符串存在
    不可以修改(增加或删除元素等)
    支持for循环
    
# 案列：
my_name = "itheima itcast boxuegu"
it_num = my_name.count("it")
new_name = my_name.replace(' ', '|')
list_name = my_name.split('|')
print(f'字符串{my_name}中有{it_num}个it')
print(f'字符串{my_name}空格被替换后，得到：{new_name}')
print(f'字符串{my_name}安装|分隔符后。结果：{list_name}')

# 字符串itheima itcast boxuegu中有2个it
# 字符串itheima itcast boxuegu空格被替换后，得到：itheima|itcast|boxuegu
# 字符串itheima itcast boxuegu安装|分隔符后。结果：['itheima itcast boxuegu']

"""



# 数据容器（序列）的切片操作
"""
序列是指:内容连续、有序，可使用下标索引的一类数据容器
列表、元组、字符串，均可以可以视为序列。

# 序列的切片操作
切片:从一个序列中，取出一个子序列
语法:序列[起始下标:结束下标:步长]

表示从序列中，从指定位置开始，依次取出元素，到指定位置结束，得到一个新序列:起始下标表示从何处开始，可以留空，留空视作从头开始
结束下标(不含)表示何处结束，可以留空，留空视作截取到结步长表示，依次取元素的间隔
    步长1表示，一个个取元素
    步长2表示，每次跳过1个元素取
    步长H表示，每次跳过N-1个元素取
    步长为负数表示，反向取(注意，起始下标和结束下标也要反向标记)
注意：此操作不会影响序列本身，而是会得到一个新的序列（列表、元组、字符串）
# 对list进行切片
my_list = [0, 1, 2, 3, 4, 5, 6]
result = my_list[1:4:1]   # 从1开始，4结束，步长1可以省略.
print(result)    # 打印[1, 2, 3]
# 对tuple进行切片
my_tuple = (0, 1, 2, 3, 4, 5, 6)
result2 = my_tuple[:]    # 从头开始切片（省略），结尾结束（省略），步长为1，可以省略；
print(result2)    # 打印(0, 1, 2, 3, 4, 5, 6)

# 对str进行切片1
my_str = "01234567"
result3 = my_str[::2]    # 从头开始，结尾结束，步长为2；
print(result3)           # 打印0246

# 对str进行切片2
my_str1 = "01234567"
result4 = my_str1[::-1]      # 从头开始，结尾结束，步长为-1
print(result4)     # 打印76543210

# 对列表进行切片2
my_list1 = [0, 1, 2, 3, 4, 5, 6]
result5 = my_list1[3:1:-1]          # 从3开始，1结束，步长为-1
print(result5)      # 打印[3, 2]

# 对元组进行切片2
my_tuple = (0, 1, 2, 3, 4, 5, 6)
result6 = my_tuple[::-2]    # 从头开始，结尾结束，步长为-2
print(result6)    # 打印(6, 4, 2, 0)


# 案例
my_str = "万过薪月，员序程马黑来，nohtyP学"    # 从字符串中得到“黑马程序员”
# 将字符串切片出来，倒序，切片 
new_str = my_str[::-1][9:14]     #首先对字符串进行切片，采用-1的方式，再取出从9开始到14结束的字符串
print(new_str)  # 打印黑马程序员
# 切片,倒序
result = my_str[5:10][::-1]
print(result)   # 打印黑马程序员
# "split分隔"，"，replace 替换"来”为空，倒序字符串
result2 = my_str.split('，')[1].replace('来', '')[::-1]
print(result2)
"""






# 数据容器：set（集合）
"""
集合，最主要的特点就是:不支持元素的重复(自带去重功能)、并且内容无序
不支持下标索引，但是支持修改。
基础语法：
# 定义字面量
{元素, 元素, 元素, ...., 元素}
# 定义变量
name = {元素, 元素, 元素, ...., 元素}
# 定义空集合
name = set()

name = {"itheima", 3, 2, 1, 2, "itcast", 4, 4, 3, 6}
name_my = set()
print(name)            # 打印{1, 2, 3, 4, 'itcast', 6, 'itheima'}
print(name_my)         # 打印set()
print(type(name))      # <class 'set'>

# 集合的一些列操作

#添加新元素
语法:集合.add(元素)。将指定元素，添加到集合内
结果:集合本身被修改，添加了新元素
注意：添加集合内相同的元素时，加不进去，因为本身就存在。
my_set = {"Hello", "word"}
my_set.add("itheima")
print(my_set)   # {'word', 'itheima', 'Hello'}

# 移除元素
语法:集合.remove(元素)，将指定元素，从集合内移除
结果:集合本身被修改，移除了元素
my_set = {"hello", "word", "welcome", "hello"}
my_set.remove("hello")
print(my_set)            # 打印{'word', 'welcome'}

# 从集合中随机取出元素
语法:集合.pop().功能:从集合中随机取出一个元素
结果:会得到一个元素的结果。同时集合本身被修改，元素被移除
my_set = {"hello", "word", "welcome", "hello"}
element = my_set.pop()
print(f"集合被取出的元素是{element}，取出后集合还有{my_set}")  # pop在集合中是随便被取的
# 打印集合被取出的元素是welcome，取出后集合还有{'word', 'hello'}

# 清空集合
语法：集合.clear()，功能，清空列表
结果:集合本身被清空
my_set = {"hello", "word", "welcome"}
my_set.clear()
print(my_set)    # 打印set()

# 取2个集合的差集
语法:集合1.difference(集合2)，功能:取出集合1和集合2的差集(集合1有而集合2没有的)
结果:得到一个新集合，集合1和集合2不变
set_1 = {4, 2, 3, 7}
set_2 = {1, 2, 6}
set_3 = set_1.difference(set_2)
print(set_3)       # {3, 4, 7}
print(set_1)       # 打印{2, 3, 4, 7}
print(set_2)       # {1, 2, 6}

# 清除2个集合的差集
语法：集合1.difference_update(集合2)
功能:对比集合1和集合2，在集合1内部，删除和集合2相同的元素。
结果:集合1被修改，集合2不变
set_1 = {4, 2, 3, 7}
set_2 = {1, 2, 6}
set_1.difference_update(set_2)
print(set_1)   # 打印{3, 4, 7}。删除了元素"2"
print(set_2)   # 打印{1, 2, 6}。保持不变

# 合并2个集合
语法:集合1.union(集合2)
功能:将集合1和集合2组合成新集合结果:得到新集合，集合1和集合2不变
set_1 = {4, 2, 3, 7}
set_2 = {1, 2, 6}
set_3 = set_1.union(set_2)
print(set_3)       # {1, 2, 3, 4, 6, 7}  不重复，无序
print(set_1)       # {2, 3, 4, 7} 不变化
print(set_2)       # {1, 2, 6} 不变化

# 统计集合的数量
语法：len(集合)
set_1 = {4, 3, 2, 3, 7}
num = len(set_1)
print(num)         # 打印4

# 集合的遍历
集合不支持下标索引，所以无法用while
set_1 = {4, 3, 2, 3, 7}
for x in set_1:
    print(x)     # 分别打印 2，3，4，7
    
# 集合的特征
可以容纳多个数据
可以容纳不同类型的数据(混装)
数据是无序存储的(不支持下标索引)
不允许重复数据存在
可以修改(增加或删除元素等)
支持for循环

# 案例
my_list = ['黑马程序员', '传智播客', '黑马程序员',
           '传智播客', 'itheima', 'itcast', 'itheima', 'itcast', 'best']   # 定义列表
set_empty = set()   # 定义空集合
for x in my_list:    # 通过for循环遍历列表
    set_empty.add(x)
print(set_empty)  # 打印集合

"""





# 字典
"""
通过字典，可以实现用key（比如查询人）取出value（比如成绩）的操作
特征：不允许key的重复，字典同集合一样，不可以使用下标索引

# 字典的定义   采用键值对
定义字面量
{key：value, key:value, ......, key:value}
定义变量
my_dist = {key：value, key:value, ......, key:value}
定义空字典
my_dict = {}
my_dict = dist()
# 基础定义
my_dict1 = {"王力宏": 98, "林俊杰": 93, "周杰伦": 77}
my_dict2 = dict()  # 定义空字典第一种方法
my_dict3 = {}      # 定义空字典第二种方法
print(my_dict1)    # 打印{'王力宏': 98, '林俊杰': 93, '周杰伦': 77}
print(type(my_dict1))    # 打印<class 'dict'>


# 字典元素不允许重复
重复后后面的元素将会覆盖原有的元素数据
# 错误案例
my_dict1 = {"王力宏": 98, "王力宏": 93, "周杰伦": 77}
print(my_dict1)   # 打印{'王力宏': 93, '周杰伦': 77}

# 字典数据的获取
语法：字典[key]可以获取到对应的Value值
my_dict1 = {"王力宏": 98, "林俊杰": 93, "周杰伦": 77}
score = my_dict1['王力宏']
print(score)   # 打印98

# 定义嵌套字典
字典的Key和Value可以是任意数据类型(Key不可为字典)
stu_score_dict = {
    "王力宏": {
        "语文": 77,
        "数学": 66,
        "熟悉": 33
    }, "周杰伦": {
        "语文": 88,
        "数学": 44,
        "英语": 78
    }, "林俊杰": {
        "语文": 60,
        "数学": 44,
        "英语": 66
    }
}

print(stu_score_dict)

# 从嵌套中获取信息
score = stu_score_dict["周杰伦"]["语文"]
print(score)  # 打印88
"""

# 字典的常用操作
"""
# my_dict = {"王力宏": 98, "林俊杰": 93, "周杰伦": 77}  # 以下操作都是基于这个字典进行操作

# 新增元素/更新元素
语法：字典[key] = Value
结果：字典被修改，新增元素或字典被修改
注意：字典Key不可以重复，所以对已存在的Key执行上述操作，就是更新Value值
my_dict["张学友"] = 88   # 新增字典元素
my_dict1["王力宏"] = 66   # 更新字典元素
print(my_dict)   # 打印{'王力宏': 66, '林俊杰': 93, '周杰伦': 77, '张学友': 88}

# 删除元素
语法:字典.pop(Key)
结果:获得指定Key的Value，同时字典被修改，指定Key的数据被删除
score = my_dict.pop('周杰伦')
print(f"字典中被移除了一个元素，结果: {my_dict}，周杰轮的
考试分数是: {score}")
# 打印字典中被移除了一个元素，结果: {'王力宏': 98, '林俊杰': 93}，周杰轮的考试分数是: 77

# 清空元素
语法：字典.clear()
结果：清空字典所以内容
my_dict.clear()
print(my_dict)             # 打印{}

# 获取全部的key   # 可以用来帮助我们做字典的遍历
语法:字典.keys()。结果:得到字典中的全部Key
keys = my_dict.keys()
print(keys)    # 打印dict_keys(['王力宏', '林俊杰', '周杰伦'])

# 字典的遍历    提供获取全部的key值来遍历
keys = my_dict.keys()
print(keys)    # 打印dict_keys(['王力宏', '林俊杰', '周杰伦'])
for x in keys:
    print(f"字典的value值是：{my_dict[x]}")
# 字典的value值是：98   字典的value值是：93   字典的value值是：77

# 遍历方式2：直接对字典进行for循环，每一次循环都是得到key
for x in my_dict:
    print(f"学典的value是:{my_dict[x]}")

# 统计字典内的元素数量
语法：len(字典)，函数
结果：统计字典中元素数量
len(my_dict)

# 字典的特点
    可以容纳多个数据
    可以容纳不同类型的数据
    每一份数据是KeyValue键值对
    可以通过Key获取到Value，Key不可重复(重复会覆盖)
    不支持下标索引
    可以修改(增加或删除更新元素等)
    支持for循环，不支持while循环

# 字典案列
date = {
    "王力宏": {
        "部门": "科技部",
        "工资": 3000,
        "级别": 1,
    },
    "周杰伦": {
        "部门": "市场部",
        "工资": 5000,
        "级别": 2,
    },
    "林俊杰": {
        "部门": "市场部",
        "工资": 7000,
        "级别": 3,
    },
    "张学友": {
        "部门": "科技部",
        "工资": 4000,
        "级别": 1,
    },
    "刘德华": {
        "部门": "市场部",
        "工资": 6000,
        "级别": 1,
    },
}
print(f"全部员工当前信息如下：{date}")
for x in date.keys():
    if date[x]["级别"] == 1:
        info_date = date[x]
        info_date['级别'] = 2
        info_date["工资"] += 1000
        date[x] = info_date

print(f"通过升值加薪后，信息如下：{date}")
"""


# 容器总结
"""
数据容器可以从以下视角进行简单的分类:
是否支持下标索引
    支持:列表、元组、字符串-序列类型
    不支持:集合、字典-非序列类型
是否支持重复元素:
    支持:列表、元组、字符串-序列类型
    不支持:集合、字典-非序列类型
是否可以修改
    支持:列表、集合、字典
    不支持:元组、字符串
    

1.基于各类数据容器的特点，它们的应用场景如下
    列表:一批数据，可修改、可重复的存储场景
    元组:一批数据，不可修改、可重复的存储场景
    字符串:一串字符串的存储场景
    集合:一批数据，去重存储场景
    字典:一批数据，可用Key检索Value的存储场景
"""



# 数据容器的通用操作
"""
1.都支持for遍历，集合字典不支持while，其他3类支持
2.都支持len(容器) 结果：统计元素个数
   max(容器)     结果：统计容器中最大值
   min(容器)     结果：统计容器中最小值
3.类型转换
list(容器)   结果：将给定容器转换为列表
注意：字典转列表时会将Value值给抛弃掉，字符串转列表时会将每一个元素取出都转换成列表的元素
str(容器)    结果：将给定容器转换为字符串
注意：字典转字符串时不会将Value值给抛弃，列表和元组转换成字符串会将[]或()保留，加上双引号
tuple(容器)  结果：将给定容器转换为元组
注意：字典转元组时会将Value值给抛弃掉，字符串转元组时会将每一个元素取出都转换成元组的元素
set(容器)    结果：将给定容器转换为集合
注意：字典转列表时会将Value值给抛弃掉，字符串转集合时会将每一个元素取出都转换成列表的元素

其他类型容器不可以转换成字典，但是字典可以转换成其他类型容器。


# 通用排序功能
sorted(容器, [reverse=True])   结果：将给定的容器排序，放入列表当中
reverse默认值为False，如果想让排序的容器进行反转，可以传入一个True。
my_list = [4, 1, 5, 7, 3, 9]
my_str = 'rgdcoshos'
my_tuple = (5, 2, 8, 4, 6)
my_set = {"abc", "xiaokeg", "lfd"}
my_dict = {"key2": 99, "key3": 77, "key1": 33}
print(sorted(my_list))
print(sorted(my_str))   # 打印['c', 'd', 'g', 'h', 'o', 'o', 'r', 's', 's']
print(sorted(my_tuple))
print(sorted(my_set))
print(sorted(my_dict))   # 打印['key1', 'key2', 'key3']

注意：排序后的结果会通通变为列表对象[]
反向排序：
my_list = [4, 1, 5, 7, 3, 9]
print(sorted(my_list, reverse=True))    # [9, 7, 5, 4, 3, 1]

"""


# 字符串的大小比较
"""
字符串进行比较就是基于数字的码值(ASCII)大小进行比较的.
# 按位比较
字符串是按位比较，也就是一位位进行对比，只要有一位大，那么整体就大。
print(f"abd大于abc，结果：{'abd' > 'abc'}")      # 打印abd大于abc，结果：True
print(f"ab大于a，结果：{'ab' > 'a'}")            # ab大于a，结果：True
print(f"key2大于key1，结果{'key2' > "key1"}")    # 大于key2大于key1，结果True
"""




